package org.eweb4j.mvc.interceptor;

import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

import org.eweb4j.cache.ActionConfigBeanCache;
import org.eweb4j.cache.InterConfigBeanCache;
import org.eweb4j.config.LogFactory;
import org.eweb4j.mvc.Context;
import org.eweb4j.mvc.config.bean.ActionConfigBean;
import org.eweb4j.mvc.config.bean.InterConfigBean;
import org.eweb4j.mvc.config.bean.Uri;
import org.eweb4j.mvc.validator.ValidatorConstant;
import org.eweb4j.mvc.view.CallBackJson;


public class InterExecution {
	private String showErrType = null;
	private Interceptor inter = null;
	private String interType = null;
	private Context context = null;
	private String error = null;

	public InterExecution(String interType, Context context) {
		this.interType = interType;
		this.context = context;
	}

	/**
	 * 找
	 * 
	 * @return
	 * @throws Exception
	 */
	public boolean findAndExecuteInter() throws Exception {
		for (InterConfigBean inter : InterConfigBeanCache.getList()) {
			String _interType = inter.getType();
			if (!interType.equals(_interType))
				continue;
			String uri = this.context.getUri();
			if (inter.getExcept().contains(uri))
				continue;
			String policy = inter.getPolicy();
			boolean isOR = "or".equalsIgnoreCase(policy) ? true : false;

			List<Uri> uris = inter.getUri();
			final int size = uris.size();
			int result = 1;
			for (int i = 0; i < size; i++) {
				Uri u = uris.get(i);
				String type = u.getType();
				String value = u.getValue();
				int c = 1;

				if ("start".equalsIgnoreCase(type) && uri.startsWith(value))
					// 以url开头
					;
				else if ("end".equalsIgnoreCase(type) && uri.endsWith(value))
					// 以url结尾
					;
				else if ("contains".equalsIgnoreCase(type)
						&& uri.contains(value))
					// 包含url
					;
				else if ("all".equalsIgnoreCase(type) && uri.equals(value))
					// 完全匹配url
					;
				else if ("regex".equalsIgnoreCase(type) && uri.matches(value))
					// 正则匹配
					;
				else if ("actions".equalsIgnoreCase(type)) {

					if (!findActionUriMapping())
						c = 0;

				} else if ("!start".equalsIgnoreCase(type)
						&& !uri.startsWith(value))
					// 不以url开头
					;
				else if ("!end".equalsIgnoreCase(type) && !uri.endsWith(value))
					// 不以url结尾
					;
				else if ("!contains".equalsIgnoreCase(type)
						&& !uri.contains(value))
					// 不包含url
					;
				else if ("!all".equalsIgnoreCase(type) && !uri.equals(value))
					// 不完全匹配url
					;
				else if ("!regex".equalsIgnoreCase(type) && !uri.matches(value))
					// 不正则匹配
					;
				else if ("!actions".equalsIgnoreCase(type)) {

					if (ActionConfigBeanCache.containsKey(uri)
							|| (ActionConfigBeanCache.getByMatches(uri,
									context.getHttpMethod())) != null) {
						// 找到了action 与当前访问的uri映射
						c = 0;
					}
				} else if ("*".equals(type)) {
					// 所有都匹配
					findActionUriMapping();
				} else
					c = 0;

				if (isOR)
					result += c;
				else {
					if (c == 0)
						break;

					result *= c;
				}

				if (i < size - 1)
					continue;

				if (result == 0)
					continue;

				this.inter = (Interceptor) Class.forName(inter.getClazz())
						.newInstance();
				this.showErrType = inter.getShowErrorType();
				this.inter.setContext(this.context);

				this.error = this.inter.intecept();

				// 如果拦截处理之后没有任何错误信息，进入下一个URI继续处理，否则显示错误信息
				if (this.error == null)
					continue;
				else {
					logErr();
					return true;
				}
			}
		}

		return false;
	}

	private boolean findActionUriMapping() {
		boolean result = false;
		Map<String, List<?>> map = null;
		if (ActionConfigBeanCache.containsKey(this.context.getUri())
				|| (map = ActionConfigBeanCache.getByMatches(
						this.context.getUri(), context.getHttpMethod())) != null) {
			// 找到了action 与当前访问的uri映射
			if (map.containsKey("mvcBean")) {
				ActionConfigBean acb = (ActionConfigBean) map.get("mvcBean")
						.get(0);
				this.context.setMvcBean(acb);
				result = true;
			}

		}

		return result;
	}

	/**
	 * 显示拦截器执行之后的错误信息
	 * 
	 * @param error
	 * @throws Exception
	 */
	public void showErr() throws Exception {

		if (ValidatorConstant.DEFAULT_LOC.equals(this.showErrType)
				|| ValidatorConstant.ALERT_LOC.equals(this.showErrType))
			this.print(
					this.context.getResponse().getWriter(),
					"<script>alert('"
							+ error
							+ "');javascript:history.go(-1)</script><center></center>");
		else if (ValidatorConstant.AJAX_OUT_LOC.equals(this.showErrType))
			this.print(this.context.getResponse().getWriter(), error);
		else if (ValidatorConstant.DWZ_JSON_LOC.equals(this.showErrType))
			this.print(this.context.getResponse().getWriter(),
					new CallBackJson(error).toString());
		else if (ValidatorConstant.JAVASCRIPT_LOC.equals(this.showErrType))
			this.print(this.context.getResponse().getWriter(), "<script>"
					+ error + "</script>");
		else {
			// 如果是填写跳转页面的话
			this.context.getRequest().setAttribute("interError", error);
			this.context
					.getRequest()
					.getRequestDispatcher(this.showErrType)
					.forward(this.context.getRequest(),
							this.context.getResponse());
		}

	}

	private void print(PrintWriter out, String err) {
		out.print(err);
		out.flush();
		out.close();
		out = null;
	}

	private void logErr() {
		StringBuilder sb = new StringBuilder();
		sb.append("MVC:拦截器拦截url：").append(this.context.getUri());
		sb.append("并输出错误信息:").append(this.error);
		LogFactory.getMVCLogger("INFO").write(sb.toString());
	}
}
